#pragma once
#include "Dispatcher.h"
#include "Channel.h"
#include <thread>
#include <queue>
#include <map>
#include <mutex>

enum class ElemType : char
{
    ADD,
    DELECT,
    MODIFY
};

enum class EventLoopModelType
{
    EPOLL,
    POLL,
    SELECT
};

struct ChannelElement
{
    enum ElemType type;
    Channel *channel;
};

class Dispatcher;

class EventLoop
{
public:
    EventLoop(EventLoopModelType type);
    EventLoop(EventLoopModelType type, const std::string threadName);
    ~EventLoop();
    //启动反应堆模型
    int8_t run();
    // 处理被激活的文件fd
    int8_t eventActive(int32_t fd, int32_t event);
    // 任务队列添加任务
    int8_t addTask(Channel *channel, ElemType type);
    // 处理任务队列中的任务
    int8_t processTask();
    // 释放channel
    int8_t freeChannel(Channel *channel);

    static int readLocalMessage(void *arg); // 读数据
    int readMessage(); // 读数据
    inline std::thread::id getThreadID() 
    {
        return m_threadID;
    }
    inline std::string getThreadName() 
    {
        return m_threadName;
    }

private:
    void taskWakeup(); // 读数据
    // 处理dispatcher中的节点
    int8_t add(Channel *channel);
    int8_t remove(Channel *channel);
    int8_t modify(Channel *channel);

private:
    bool m_isRun;
    // 该指针指向子类的实例 epoll poll select
    Dispatcher *m_dispatcher;
    // 任务队列
    std::queue<ChannelElement *> m_taskQ;
    // map
    std::map<int, Channel *> m_channelMap;
    // 线程id， name
    std::thread::id m_threadID;
    std::string m_threadName;
    std::mutex m_mutex;
    int32_t m_socketPair[2]; // 存储本地通信的fd 通过socketpair()初始化  socketPair[0]发送数据    socketPair[1]接收数据
};
